﻿using System;
using System.Collections.Generic;
using System.Text;

namespace UFrameWork
{
    /// <summary>
    /// 网络心跳包
    /// </summary>
    public class HeartBeat
    {
        /// <summary>
        /// 最后发送的时间
        /// </summary>
        public DateTime LastSendTime = DateTime.Now;

        /// <summary>
        /// 最后接收到的时间
        /// </summary>
        public DateTime LastReceiveTime = DateTime.Now;

        /// <summary>
        /// 超时时间
        /// </summary>
        public int TimeOut { get; private set; }

        /// <summary>
        /// 上一个心跳包延时时间
        /// </summary>
        private int PreDelay = 0;

        /// <summary>
        /// 心跳消息内容
        /// </summary>
        private const string BeatFlag = "beat";

        /// <summary>
        /// 网络客户端
        /// </summary>
        private UNetClient client;

        /// <summary>
        /// 心跳包数组
        /// </summary>
        private byte[] HeatByte;

        /// <summary>
        /// 是否为已超时
        /// </summary>
        /// <returns></returns>
        public bool IsTimeOut()
        {
            bool state = (LastSendTime - LastReceiveTime).TotalSeconds >= TimeOut;
            if (state)
            {
                LastSendTime    = DateTime.Now;
                LastReceiveTime = DateTime.Now;
            }
            return state;
        }

        /// <summary>
        /// 网络延时
        /// </summary>
        public int Delay
        {
            get
            {
                if (LastSendTime < LastReceiveTime)
                {
                    PreDelay = (int)(LastReceiveTime - LastSendTime).TotalMilliseconds;
                }
                return PreDelay;
            }
        }

        /// <summary>
        /// 心跳包管理
        /// </summary>
        /// <param name="timeoute">超时时间</param>
        public HeartBeat(UNetClient client,int timeOut = 20)
        {
            this.client = client;
            SetBeatTimeOut(timeOut);
            HeatByte = Encoding.UTF8.GetBytes(BeatFlag + UNetClient.EndFlag);
        }

        /// <summary>
        /// 设置心跳包超时时间
        /// </summary>
        /// <param name="timeOute">超时时间秒</param>
        public void SetBeatTimeOut(int timeOut)
        {
            TimeOut = timeOut;
        }

        /// <summary>
        /// 是否为心跳消息
        /// </summary>
        public bool IsBeatMsg(string msg)
        {
            if ((msg.ToLower() != BeatFlag))
            {
                return false;
            }
            LastReceiveTime = DateTime.Now;
            return true;
        }

        /// <summary>
        /// 发送心跳包
        /// </summary>
        public void SendBeat()
        {
            if ((DateTime.Now - LastSendTime).TotalMilliseconds > 3000)
            {
                LastSendTime = DateTime.Now;
                client.Send(HeatByte, 0, HeatByte.Length);
            }
        }
    }
}